<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>Document</title>
</head>
<body>
    <script>
        // 题目1:
        //知识储备:
        // 1.prototype:js中每个对象都有prototype属性/每个构造函数都有个属性叫原型;用来返回对象类型原型的引用,为某个特定的类声明通用的变量或函数[即用来给相同类型的所有对象添加共享属性]
        // 2.构造函数/构造器
        // 3.实例对象
        // 4.作用域
        // 5.js的解析和执行过程:new Foo()就去调用原型对象，new Foo就调用它的私有属性
        // 6.变量提升,函数提升
        // 7.操作符优先级

        // function a() {  };
        // a.get = function() {
        //     console.log('555');
        // }
        // a.get();
        // function Foo1() {
        //     this.haha = function () {//在Foo函数中声明的getName函数没有加var/let关键字，默认全局作用域。
        //         console.log('a');
        //     };
        //     this.value='999';
        //     return this;
        // };
        // new Foo1().haha();//创建实例对象,访问构造函数,访问构造函数的方法haha() haha必须加括号
        function Foo() {
            getName = function () {//在Foo函数中声明的getName函数没有加var/let关键字，默认全局作用域。对全局函数getName的重新赋值
                console.log(1);
            };
            return this;
        };
        Foo.getName = function () {//Foo函数中的属性getName()
            console.log(2);
        };
        // Foo.prototype=new Foo1();  把Foo1的所有属性方法都继承给Foo
        Foo.prototype.getName = function () {  //Foo函数的原型方法
            console.log(3);
        };
        var getName = function () {  //对全局函数重新赋值
            console.log(4);
        };
        function getName() {//全局函数getName的创建
            console.log(5);
        };
        // window对象表示浏览器打开的窗口。js的函数，全局对象和变量都会自动成为window对象内的成员
        // console.log(Foo);//输出是整个函数体Foo
        // console.log(Foo());//输出是window对象,==this 【如果Foo()函数没有return this,输出是undefined】
        // console.log(new Foo());//Foo {}   [new Foo()的操作等同于new Foo,都是创建一个实例对象]
        // getName();//4   getName()是全局函数的引用---4会把5覆盖
        // Foo.getName();//2
        // Foo().getName();//1  ===>  Foo()是普通函数的调用返回this  this.getName()
        // getName();//1    全局函数getName()
        // new Foo.getName();//2  ==>new (Foo.getName())
        // new Foo().getName();//3 ==>(new Foo()).getName()  new Foo()得到一个实例对象,调用构造函数Foo(),调用Foo的原型方法
        // new new Foo().getName();//3  [new Foo() > . > new Foo]   ===> new (new Foo().getName())
        // console.log(new Foo().getName());//undefined
        // console.log(new Foo.getName());//Foo.getName(){}


        // 题目变形,强化
        function A () {
            this.get = function () {
                console.log('a');
                return {
                    get:get
                }
            };
            get = function () {
                console.log('1');
            };
            return this;
        };
        A.get = function () {  
            console.log('2');
        };
        A.prototype.get = function () {  
            console.log('3');
        };
        var get = function () {  
            console.log('4');
        };
        function get () {
            console.log('5');
        };
        // A.get();//2
        // get();//4
        // console.log(A());//window对象
        // A().get();//1
        // get();//1
        // new A.get();//2
        new A().get();//a
        new A().get().get();//a 1
        new new A().get();//a


        // 题目2：
        //function excute(){
        // }
        // excute()
        // 要求执行的结果是：3秒后输出1, 2秒后输出2, 1秒后输出1，总执行时间是6秒

    </script>
</body>
</html>